package com.gopay.solution.service.solu.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.solution.PayChanExtConstants;
import com.gopay.common.domain.solution.SolutionResponse;
import com.gopay.common.domain.solution.SsTransPayChanDtlExt;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.solution.SolutionExtRemoteService;
import com.gopay.remote.solution.vo.SolutionExtInfo;
import com.gopay.solution.dao.ext.SsTransPayChanDtlExtDao;

/**
 * 方案扩展实现接口
 *
 * @SolutionExtServiceImpl
 * @author dongdh
 * @2016/8/8 8:53  www.gopay.com.cn Inc.All rights reserved.
 */

@Service("soluExtService")
public class SolutionExtServiceImpl implements SolutionExtRemoteService {

    private Log logger = LogFactory.getLog(getClass());


    @Autowired
    private SsTransPayChanDtlExtDao extDao;

    /**
     * 获取清算渠道方案扩展值.
     * @param acctId
     * @param intTxnCd
     * @param payChannel
     * @param name  扩展字段名字， 取自solution 常量
     * @return
     */
    @Override
    public SolutionResponse getPayChanExtVal(String acctId, String intTxnCd, String payChannel, String name) {

        SolutionResponse response = new SolutionResponse();
        response.setSucceed(true);
        response.setRespCode(ProcCodeConstants.PROC_CODE_000S1000);
        try {

            logger.info("获取清算渠道方案扩展值:acctId=" + acctId
                    + ",intTxnCd=" + intTxnCd + ",payChannel="
                    + payChannel + ",name=" + name);
            //参数校验
            if (StringUtils.isBlank(acctId)
                    || StringUtils.isBlank(intTxnCd)
                    || StringUtils.isBlank(payChannel)
                    || StringUtils.isBlank(name)) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E5266, "参数错误");
            }

            SsTransPayChanDtlExt val = extDao.getExtVal(acctId, intTxnCd, payChannel, name);
            response.setResponse(val.getValue());
        } catch (Exception e) {
           // e.printStackTrace();
        	logger.error("获取清算渠道方案扩展出错："+e.getMessage());
            response.setSucceed(false);
            if (e instanceof GopayException) {
                response.setRespCode(((GopayException) e).getErrCode());
            } else {
                response.setRespCode(ProcCodeConstants.PROC_CODE_100F1002);
            }
        }
        return response;
    }
    
    @SuppressWarnings("unchecked")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void saveOrUpdateChanDtlExt(SolutionExtInfo solutionExtVo){

        Map<String, String> extMap = solutionExtVo.getExtMap();
        JSONObject channelSolution = solutionExtVo.getChannelSolution();
        String  OperId = solutionExtVo.getOperId();
        String payChannel=solutionExtVo.getPayChannel();
        String acctId=solutionExtVo.getAcctId();
        String intTxnCd=solutionExtVo.getIntTxnCd();
        String type=solutionExtVo.getType();
        List<SsTransPayChanDtlExt> extList = new ArrayList<>();

        for (String key : extMap.keySet()) {

            if (key.startsWith("ext_")) {
                SsTransPayChanDtlExt ssTransPayChanDtlExt = new SsTransPayChanDtlExt();
                ssTransPayChanDtlExt.setPayChannel(payChannel);
                ssTransPayChanDtlExt.setAcctId(acctId);
                ssTransPayChanDtlExt.setGopayIntTxnCd(intTxnCd);
                ssTransPayChanDtlExt.setName(key);
                ssTransPayChanDtlExt.setType(type);
                ssTransPayChanDtlExt.setValue(extMap.get(key));
                ssTransPayChanDtlExt.setCreatedOperId(OperId);
                ssTransPayChanDtlExt.setCreatedTs(new Date());
                extList.add(ssTransPayChanDtlExt);
            }
        }
        if(StringUtils.isNotBlank(acctId)){
            SsTransPayChanDtlExt payChanDtlExtSign =
                    findPayChanDtlExt(acctId, intTxnCd
                            ,payChannel, type, channelSolution == null ?
                                    PayChanExtConstants.IS_PERSONAL_SIGN : PayChanExtConstants.EXT_IS_OPEN_MERCHANTMODEL);
                SsTransPayChanDtlExt ssTransPayChanDtlExt = new SsTransPayChanDtlExt();
                ssTransPayChanDtlExt.setPayChannel(payChannel);
                ssTransPayChanDtlExt.setAcctId(acctId);
                ssTransPayChanDtlExt.setGopayIntTxnCd(intTxnCd);
                if(channelSolution != null) {
                    ssTransPayChanDtlExt.setName( PayChanExtConstants.EXT_IS_OPEN_MERCHANTMODEL);
                    ssTransPayChanDtlExt.setValue(channelSolution.toString());
                } else {
                    ssTransPayChanDtlExt.setName(PayChanExtConstants.IS_PERSONAL_SIGN);
                    ssTransPayChanDtlExt.setValue("1"); //个性化过
                }
                ssTransPayChanDtlExt.setType(type);
                ssTransPayChanDtlExt.setCreatedOperId(OperId);
                ssTransPayChanDtlExt.setCreatedTs(new Date());
                extList.add(ssTransPayChanDtlExt);
            }

        if (extList != null && extList.size() > 0) {
            List<SsTransPayChanDtlExt> list = new ArrayList<>();
            for (SsTransPayChanDtlExt ext : extList) {
                if (ext != null && StringUtils.isNotBlank(ext.getGopayIntTxnCd())) {
                    SsTransPayChanDtlExt payChanDtlExt =
                            findPayChanDtlExt(ext.getAcctId(), ext.getGopayIntTxnCd()
                                    ,ext.getPayChannel(), type, ext.getName());

                    if(null != payChanDtlExt){
                        payChanDtlExt.setValue(ext.getValue());
                        payChanDtlExt.setLastUpdOperId(OperId);
                        payChanDtlExt.setLastUpdTs(new Date());
                        list.add(payChanDtlExt);
                    } else {
                        list.add(ext);
                    }
                }
            }
            extDao.saveOrUpdateAll(list);
        } else {
            //清空数据

            StringBuilder hql=new StringBuilder();
            hql.append(" from SsTransPayChanDtlExt where  gopayIntTxnCd =:intTxnCd");
            hql.append(" and payChannel =:payChannel and type = :type ");
            Map<String, Object> param = new HashMap<String, Object>();
            if(StringUtils.isNotBlank(acctId)){
                param.put("acctId", acctId);
                hql.append(" and acctId =:acctId");
                hql.append(" and name !=:name");
                param.put("name", PayChanExtConstants.IS_PERSONAL_SIGN);
            }
            param.put("intTxnCd", intTxnCd);
            param.put("payChannel", payChannel);
            param.put("type", type);

            List<SsTransPayChanDtlExt> payChanDtlExtList = extDao.findByHql(hql.toString(), param);

            extDao.deleteAll(payChanDtlExtList);
        }

    }
    
    private SsTransPayChanDtlExt findPayChanDtlExt(String acctId, String intTxnCd, String payChannel, String type, String name) {
        StringBuilder hql=new StringBuilder();
        hql.append("from SsTransPayChanDtlExt where  gopayIntTxnCd =:intTxnCd");
        hql.append(" and payChannel =:payChannel and type = :type and name = :name");
        Map<String, Object> param=new HashMap<String, Object>();
        if(StringUtils.isNotBlank(acctId)){
            param.put("acctId", acctId);
           hql.append(" and acctId =:acctId"); 
        }
        param.put("intTxnCd", intTxnCd);
        param.put("payChannel", payChannel);
        param.put("name", name);
        param.put("type", type);
        List<SsTransPayChanDtlExt> PayChanDtlExtList = extDao.findByHql(hql.toString(), param);
        return (PayChanDtlExtList == null || PayChanDtlExtList.size() < 1) ? null : PayChanDtlExtList.get(0);
    }


    public List<SsTransPayChanDtlExt> findPayChanDtlExtList(SolutionExtInfo solutionExtVo) {
        String payChannel=solutionExtVo.getPayChannel();
        String acctId=solutionExtVo.getAcctId();
        String intTxnCd=solutionExtVo.getIntTxnCd();
        String type=solutionExtVo.getType();
        StringBuilder hql=new StringBuilder();
        hql.append("from SsTransPayChanDtlExt where  gopayIntTxnCd =:intTxnCd");
        hql.append(" and payChannel =:payChannel and type = :type");
        Map<String, Object> param=new HashMap<String, Object>();
        if(StringUtils.isNotBlank(acctId)){
            param.put("acctId", acctId);
            hql.append(" and acctId =:acctId");
        }
        param.put("intTxnCd", intTxnCd);
        param.put("payChannel", payChannel);
        param.put("type", type);
        return extDao.findByHql(hql.toString(), param);
    }
}
